package edu.arizona.mindseye.event;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import edu.arizona.mindseye.event.enums.EventType;

/**
 * @author wkerr
 *
 */
public class EventManager {
	private static EventManager _mgr = null;

	
	private boolean _dispatch;
	private LinkedList<Event> _queue;
	
	/** Listen for any events of a given type. */
	private Map<EventType,List<EventListener>> _all;
	
	private EventManager() { 
		_queue = new LinkedList<Event>();
		
		_all = new HashMap<EventType,List<EventListener>>();
		for (EventType type : EventType.values()) { 
			_all.put(type, new ArrayList<EventListener>());
		}
	}
	
	public static EventManager inst() {
		if (_mgr == null)
			_mgr = new EventManager();
		return _mgr;
	}
	
	/**
	 * Register for all events of a given type.
	 * @param event
	 * @param callback
	 */
	public void register(EventType event, EventListener callback) { 
		_all.get(event).add(0, callback);
	}
	
	/**
	 * Directly route this message to the people who need it.
	 * Should only be called internally.
	 * @param e
	 */
	public void dispatch(Event e) { 
		if (_dispatch) { 
			_queue.add(e);
			return;
		}
		
		_dispatch = true;
		for (EventListener callback : _all.get(e.getId())) { 
			callback.onEvent(e);
		}
		_dispatch = false;
		
		while (!_queue.isEmpty()) { 
			Event event = _queue.pop();
			dispatch(event);
		}
		
	}
}
